﻿using System;
using System.Xml.Serialization;
using System.Text;
using System.IO;

using Fuse8.DomainFramework.Common;

namespace Fuse8.ContentManagementFramework.SystemFacade.Utilities
{
    public class PlainXmlSerializer
    {
        public XmlSerializer Serializer { get; protected set; }

        public PlainXmlSerializer()
        { }
        
        public PlainXmlSerializer(Type entityType)
        {
            Guard.ArgumentNotNull(entityType, "entityType");

            Serializer = new XmlSerializer(entityType);
        }

        internal string InnerSerialize(object obj)
        {
            if (Serializer == null)
            {
                throw new ArgumentNullException("Serializer isn't defined");
            }
            
            StringBuilder sb = new StringBuilder();
            using (StringWriter sw = new StringWriter(sb))
            {
                Serializer.Serialize(sw, obj);
            }

            return sb.ToString();
        }

        internal object InnerDeserialize(string storedObj)
        {
            if (Serializer == null)
            {
                throw new ArgumentNullException("Serializer isn't defined");
            }
            
            object result = null;

            using (StringReader sr = new StringReader(storedObj))
            {
                result = Serializer.Deserialize(sr);
            }

            return result;
        }
    }

    public class PlainXmlSerializer<T> : PlainXmlSerializer where T : class, new()
    {
        private static object _syncRoot = new object();

        private static PlainXmlSerializer _instance = new PlainXmlSerializer(typeof(T));

        public static string Serialize(T obj)
        {
            Guard.ArgumentNotNull(obj, "obj");

            return _instance.InnerSerialize(obj);
        }

        public static T Deserialize(string storedObj)
        {
            Guard.ArgumentNotEmpty(storedObj, "storedObj");

            return (T)_instance.InnerDeserialize(storedObj);
        }
    }
}
